package io.xccit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.xccit.clients.IProductClients;
import io.xccit.mapper.IOrderMapper;
import io.xccit.pojo.order.Order;
import io.xccit.pojo.param.OrderParam;
import io.xccit.pojo.param.ProductCollectParam;
import io.xccit.pojo.product.Product;
import io.xccit.pojo.vo.CartVO;
import io.xccit.pojo.vo.OrderVO;
import io.xccit.result.AjaxResult;
import io.xccit.service.IOrderService;
import io.xccit.to.OrderToProduct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author CH_ywx
 * @date 2023-09-20
 * @description
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<IOrderMapper, Order> implements IOrderService {

    @Autowired
    private IOrderMapper orderMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private IProductClients productClients;

    /**
     * 生成/保存订单
     *
     * @param orderParam
     * @return
     */
    @Transactional //开启事务
    @Override
    public AjaxResult saveOrder(OrderParam orderParam) {
        // 购物车ID集合
        List<Integer> cartIds = new ArrayList<>();
        // 消息队列实体集合
        List<OrderToProduct> orderToProducts = new ArrayList<>();
        // 订单集合
        List<Order> orders = new ArrayList<>();

        //用户 ID
        Integer userId = orderParam.getUserId();
        long orderId = System.currentTimeMillis();
        List<CartVO> products = orderParam.getProducts();
        for (CartVO cartVO : products) {
            //封装购物车ID
            cartIds.add(cartVO.getId());
            //封装消息队列对象
            OrderToProduct orderToProduct = new OrderToProduct();
            orderToProduct.setProductId(cartVO.getProductId());
            orderToProduct.setNum(cartVO.getNum());
            orderToProducts.add(orderToProduct);
            //封装订单
            Order order = new Order();
            order.setOrderId(orderId);
            order.setOrderTime(orderId);
            order.setUserId(userId);
            order.setProductId(cartVO.getProductId());
            order.setProductNum(cartVO.getNum());
            order.setProductPrice(cartVO.getPrice());
            orders.add(order);
        }
        //TODO 订单数据批量保存
        boolean saved = saveBatch(orders);
        if (saved == false){
            return AjaxResult.builder().code(201).message("订单生成失败").data(null).build();
        }
        //TODO 发送购物车消息-->订单生成后购物车列表需要清除
        rabbitTemplate.convertAndSend("topic.ex","clear.cart",cartIds);
        //TODO 发送商品服务消息-->订单生成后,商品的库存需要-1或更多,以购物车数量为准
        rabbitTemplate.convertAndSend("topic.ex","sub.number",orderToProducts);

        return AjaxResult.builder().code(200).message("订单生成完毕").data(null).build();
    }

    /**
     * 根据用户ID查询订单
     *
     * @param userId
     * @return
     */
    @Override
    public AjaxResult listOrder(Integer userId) {
        //TODO 查询所有订单
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getUserId,userId);
        List<Order> orders = orderMapper.selectList(wrapper);
        //TODO 订单分组
        Map<Long, List<Order>> orderMap = orders.stream().collect(Collectors.groupingBy(Order::getOrderId));
        //TODO 查询所有商品ID
        List<Integer> productIds = orders.stream().map(Order::getProductId).collect(Collectors.toList());
        //TODO 获取商品详情--->远程调用商品服务详情接口
        ProductCollectParam productCollectParam = new ProductCollectParam();
        productCollectParam.setProductIds(productIds);
        List<Product> products = productClients.selectCartProductByIds(productCollectParam);
        Map<Integer, Product> productMap = products.stream().collect(Collectors.toMap(Product::getProductId, t -> t));
        //TODO 结果封装
        List<List<OrderVO>> result = new ArrayList<>();
        //TODO 遍历订单
        for (List<Order> orderList : orderMap.values()) {
            List<OrderVO> orderVOS = new ArrayList<>();
            //TODO 遍历订单项
            for (Order order : orderList) {
                //TODO 封装订单
                OrderVO orderVO = new OrderVO();
                //属性复制
                BeanUtils.copyProperties(order,orderVO);
                //缺省属性手动赋值
                Product product = productMap.get(order.getProductId());
                orderVO.setProductName(product.getProductName());
                orderVO.setProductPicture(product.getProductPicture());
                orderVOS.add(orderVO);
            }
            result.add(orderVOS);
        }
        return AjaxResult.build(200,"订单结果查询完成",result);
    }
}
